﻿#region

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using ylyfDataConnectionManager.Common;
using ylyfDataEntityConverter.Common;
using ylyfDataEntityConverter.GenerticEntityConverter;

#endregion

namespace ylyfDataConnectionManager.Command
{
    public class HiDbCommand : IDisposable
    {
        internal HiDbCommand(DbCommand command, HiDataBase database)
        {
            if (command == null || database == null)
                throw new NullReferenceException();
            Command = command;
            SourceDataBase = database;
        }

        private HiDataBase SourceDataBase { get; }
        private DbCommand Command { get; }

        public CommandType CommandType
        {
            get => Command.CommandType;
            set => Command.CommandType = value;
        }

        public string CommandText
        {
            get => Command.CommandText;
            set => Command.CommandText = value;
        }

        public int CommandTimeout
        {
            get => Command.CommandTimeout;
            set => Command.CommandTimeout = value;
        }

        public DbTransaction Transaction
        {
            get => Command.Transaction;
            set => Command.Transaction = value;
        }

        public DbConnection Connection
        {
            get => Command.Connection;
            set => Command.Connection = value;
        }


        public DbParameterCollection Parameters => Command.Parameters;

        public void Dispose()
        {
            Command?.Connection?.Dispose();
            Command?.Dispose();
            GC.SuppressFinalize(this);
        }


        private void CommandConnectionOpen()
        {
            if (Command.Connection == null || Command.Connection.State == ConnectionState.Broken ||
                string.IsNullOrWhiteSpace(Command.Connection.ConnectionString))
                Command.Connection = SourceDataBase.CreateConnection();
            if (Command.Connection.State == ConnectionState.Closed)
                Command.Connection.Open();
        }

        ~HiDbCommand()
        {
            Dispose();
        }

        #region 执行相关函数

        public int ExecuteNonQuery()
        {
            try
            {
                CommandConnectionOpen();
                int result = Command.ExecuteNonQuery();
                return result;
            }
            finally
            {
                try
                {
                    if (Transaction == null)
                        Command.Connection.Close();
                }
                catch
                {
                }
            }
        }

        public DataTable ExecuteDataTable()
        {
            try
            {
                CommandConnectionOpen();
                using (var reader = Command.ExecuteReader())
                {
                    DataTable table = new DataTable();
                    table.Load(reader);
                    return table;
                }
            }
            finally
            {
                try
                {
                    if (Transaction == null)
                        Command.Connection.Close();
                }
                catch
                {
                }
            }
        }

        public DataSet ExecuteDataSet()
        {
            using (DataAdapter adapter = SourceDataBase.GetDataAdapter())
            {
                ((IDbDataAdapter) adapter).SelectCommand = Command;
                DataSet set = new DataSet();
                adapter.Fill(set);
                return set;
            }
        }

        public List<T> ExecuteEntity<T>(EntityConverter<T> Converter = null) where T : new()
        {
            var table = ExecuteDataTable();
            if (Converter == null)
                Converter = new DataEntityConverter<T>();
            return Converter.RetriveEntity(table);
        }

        public object ExecuteScalar()
        {
            try
            {
                CommandConnectionOpen();
                var data = Command.ExecuteScalar();
                return data;
            }
            finally
            {
                try
                {
                    if (Transaction == null)
                        Command.Connection.Close();
                }
                catch
                {
                }
            }
        }

        #endregion

        #region 添加参数相关函数

        public void AddParameter(DbParameter parameter)
        {
            Parameters.Add(parameter);
        }

        public void AddParameter(DbParameter[] parameters)
        {
            if (parameters == null || parameters.Length <= 0)
                return;
            Parameters.AddRange(parameters);
        }

        public void AddParameter(string name, object value)
        {
            Parameters.Add(SourceDataBase.CreateParameter(name, value));
        }

        public void AddParameter(string name, object value, DbType dbtype, int size,
            ParameterDirection direction, bool IsNullable = true)
        {
            Parameters.Add(SourceDataBase.CreateParameter(name, value, dbtype, size, direction, IsNullable));
        }

        #endregion
    }
}